package com.h3c.nem.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eos.common.constant.StatusCodeEnum;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.h3c.nem.entity.EducationInfo;
import com.h3c.nem.entity.EducationResponse;
import com.h3c.nem.entity.QualificationInfo;
import com.h3c.nem.model.EosResponse;
import com.h3c.nem.model.IDocResponseModel;
import com.h3c.nem.model.OcrTokenModel;
import com.h3c.nem.model.ai.ChatInfoModel;
import com.h3c.nem.model.ai.req.AIReq;
import com.h3c.nem.model.ai.resp.AIResp;
import com.h3c.nem.service.EducationInfoService;
import com.h3c.nem.utils.*;
import com.h3c.nem.vo.EducationVO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author wys45664
 * @Creat 2023/10/10 15:39
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class EducationInfoServiceImpl implements EducationInfoService {
    @Value("${ocr.education.token}")
    private String ocrTokenUrl;
    @Value("${ocr.identify,url}")
    private String ocrIdentifyUrl;
    private final AiUtil aiUtil;
    private final RestTemplate restTemplate;

    public String getOcrToken() {
        String token = RedisUtil.get("OcrToken");
        if (!org.springframework.util.StringUtils.hasText(token)) {
            Map<String, String> body = Maps.newHashMap();
            body.put("account", "ocr_nem");
            body.put("password", "123");
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Auth-Type", "DB");
            HttpEntity<Object> entity = new HttpEntity<>(body, httpHeaders);
            // 使用ParameterizedTypeReference进行包装
            ParameterizedTypeReference<OcrTokenModel> reference = new ParameterizedTypeReference<OcrTokenModel>() {
            };
            ResponseEntity<OcrTokenModel> response = restTemplate.exchange(ocrTokenUrl, HttpMethod.POST, entity, reference, new HashMap<>());
            token = response.getBody().getToken();
            if (StringUtils.isNotEmpty(token)) {
                log.info("获取OCR通用token成功");
            }
            RedisUtil.setEx("OcrToken", token, 1, TimeUnit.HOURS);
        }
        return token;
    }
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class EosTokenModel {
        private String token;
        private HashMap<String, Object> info;
    }
    @Override
    public EducationVO checkEducationInfo(EducationInfo educationInfo, MultipartFile file) throws IOException {

        Resource resource = getResource(file);
        // Request body
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("imageFile", resource);
        // 组合body和header
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        String ocrToekn = getOcrToken();
        headers.add("Authorization", ocrToekn);
        HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
        // 使用ParameterizedTypeReference进行包装
        ParameterizedTypeReference<EducationResponse> reference = new ParameterizedTypeReference<EducationResponse>() {
        };
        RestTemplate restTemplate = new RestTemplate();
        // 发送请求
        ResponseEntity<EducationResponse> response = restTemplate.exchange(ocrIdentifyUrl, HttpMethod.POST, entity, reference);
        //获取OCR识别信息
        String str = response.getBody().getData();
//        EducationInfo educationInfo1 = EducationInfo.builder().name("段佳祺").major("英语").degreeNumber("1058942017007323").degreeDate("2017.6.31").awardUnit("海北大学").build();
        EducationInfo educationInfo2 = doAiContent(str);
        EducationVO educationVO = getReminderInfo(educationInfo, educationInfo2);
        return educationVO;
    }

    @Override
    public EducationVO checkQualificationInfo(QualificationInfo qualificationInfo, MultipartFile file) throws IOException {
        Resource resource = getResource(file);
        // Request body
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("imageFile", resource);
        // 组合body和header
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        String ocrToekn = getOcrToken();
        headers.add("Authorization", ocrToekn);
        HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
        // 使用ParameterizedTypeReference进行包装
        ParameterizedTypeReference<EducationResponse> reference = new ParameterizedTypeReference<EducationResponse>() {
        };
        RestTemplate restTemplate = new RestTemplate();
        // 发送请求
        ResponseEntity<EducationResponse> response = restTemplate.exchange(ocrIdentifyUrl, HttpMethod.POST, entity, reference);
        //获取OCR识别信息
        String str = response.getBody().getData();
//        QualificationInfo qualificationInfo1 = QualificationInfo.builder().name("段佳琪 ").major("俄语").schoolName("海南").enrollmentDate("2017年09月01日").graduateDate("2020年03月30日").level("硕士研究生").learnForm("非全日制").certificateId("10217120200125041").build();
        QualificationInfo qualification = doAiContentQualification(str);
        EducationVO educationVO = getTipInfo(qualificationInfo, qualification);
        return educationVO;
    }
    public EducationVO getTipInfo(QualificationInfo userQualificationInfo,QualificationInfo aiQualificationInfo) {
        ArrayList<String> strList = new ArrayList<>();
        if (StringUtils.isNotEmpty(aiQualificationInfo.getName())) {
            if (!aiQualificationInfo.getName().equals(userQualificationInfo.getName().replaceAll(" ",""))) {
                userQualificationInfo.setName(aiQualificationInfo.getName());
                strList.add("姓名");
            }
        }
        if (StringUtils.isNotEmpty(aiQualificationInfo.getLevel())) {
            if (!aiQualificationInfo.getLevel().equals(userQualificationInfo.getLevel().replaceAll(" ",""))) {
                userQualificationInfo.setLevel(aiQualificationInfo.getLevel());
                strList.add("层次");
            }
        }
        if (StringUtils.isNotEmpty(aiQualificationInfo.getLearnForm())) {
            if (!aiQualificationInfo.getLearnForm().equals(userQualificationInfo.getLearnForm().replaceAll(" ",""))) {
                userQualificationInfo.setLearnForm(aiQualificationInfo.getLearnForm());
                strList.add("学习形式");
            }
        }
        if (StringUtils.isNotEmpty(aiQualificationInfo.getSchoolName())) {
            if (!aiQualificationInfo.getSchoolName().equals(userQualificationInfo.getSchoolName().replaceAll(" ",""))) {
                userQualificationInfo.setSchoolName(aiQualificationInfo.getSchoolName());
                strList.add("学校名称");
            }
        }
        if (StringUtils.isNotEmpty(aiQualificationInfo.getEnrollmentDate())) {
            if (!aiQualificationInfo.getEnrollmentDate().equals(userQualificationInfo.getEnrollmentDate().replaceAll(" ",""))) {
                userQualificationInfo.setEnrollmentDate(aiQualificationInfo.getEnrollmentDate());
                strList.add("入学日期");
            }
        }
        if (StringUtils.isNotEmpty(aiQualificationInfo.getGraduateDate())) {
            if (!aiQualificationInfo.getGraduateDate().equals(userQualificationInfo.getGraduateDate().replaceAll(" ",""))) {
                userQualificationInfo.setGraduateDate(aiQualificationInfo.getGraduateDate());
                strList.add("毕(结)业日期");
            }
        }
        if (StringUtils.isNotEmpty(aiQualificationInfo.getCertificateId())) {
            if (!aiQualificationInfo.getCertificateId().equals(userQualificationInfo.getCertificateId().replaceAll(" ",""))) {
                userQualificationInfo.setCertificateId(aiQualificationInfo.getCertificateId());
                strList.add("证书编号");
            }
        }
        String result = "0";
        if (strList.size()!=0) {
            result = strList.stream().collect(Collectors.joining("、")) + "--->与上传图片不一致,已帮您刷新,请再次核对。";
        }
        EducationVO educationVO = new EducationVO();
        educationVO.setQualificationInfo(userQualificationInfo);
        educationVO.setReminderInfo(result);
        return educationVO;
    }

    /**
     * 将MultipartFile转化为resource
     *
     * @param file MultipartFile
     * @return
     */
    public static Resource getResource(MultipartFile file) throws IOException {
        // 将 MultipartFile 转化为 Resource
        return new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename();
            }

            @Override
            public long contentLength() {
                return file.getSize();
            }
        };
    }

    public EducationInfo doAiContent(String ocrContent) {
        String currentUserAccount = CommonUtil.getActivUser().getAccount();
        //Ai入参
        String askContent ="从<学历信息>中找出关键信息，返回json串(用我给你的英文字段为name,关键信息为value,如果获取不到则为null)给我。\n" +
                "日期类按照YYYY年MM月DD的格式返回\n" +
                "其中学位证书编号只取数字不保留空格\n" +
                "\n" +
                " name(姓名)\n" +
                " degreeDate(获取学位日期)\n" +
                " awardUnit(学位授予单位)\n" +
                " major(学科专业)\n" +
                " degreeNumber(学位证书编号)\n" +
                " \n" +
                "<学历信息>:" + "\n" + ocrContent;
        AIReq build = new AIReq();
        ChatInfoModel chatInfoModel = new ChatInfoModel();
        log.info("AI识别入参为:{}", askContent);
        chatInfoModel.setContent(askContent);
        build.setChatInfo(chatInfoModel);
        build.setUserId(currentUserAccount);
        //获取当前IP
        build.setIp("10.19.3.36");
        AIResp aiResp = aiUtil.gpt35(build);
        String answer = "";
        if (!aiResp.getAnswerStatus().equals("SUCCESS")) {
            log.error("Ai获取OCR信息失败", JSON.toJSONString(aiResp));
        } else {
            answer = aiResp.getMessage().getContent();
            log.info("Ai获取OCR信息成功", answer);
        }
        Gson gson = new Gson();
        EducationInfo education = gson.fromJson(answer, EducationInfo.class);
        return education;
    }
    public QualificationInfo doAiContentQualification(String ocrContent) {
        String currentUserAccount = CommonUtil.getActivUser().getAccount();
        //Ai入参
        String askContent = "从<学历信息>中找出关键信息，返回json串(用我给你的英文字段为name,关键信息为value)给我。注意:证书编号之间如果有空格则去掉\n" +
                "日期类按照YYYY年MM月DD的格式返回\n" +
                "其中证书编号只取数字不保留空格\n" +
                " name(姓名)\n" +
                " enrollmentDate(入学日期)\n" +
                " graduateDate(毕(结)业日期)\n" +
                " schoolName(学校名称)\n" +
                " major(专业)\n" +
                " level(层次)\n" +
                " learnForm(学习形式)\n" +
                " certificateId(证书编号)\n" +
                "<学历信息>:\n"+ocrContent;
        AIReq build = new AIReq();
        ChatInfoModel chatInfoModel = new ChatInfoModel();
        log.info("AI识别入参为:{}", askContent);
        chatInfoModel.setContent(askContent);
        build.setChatInfo(chatInfoModel);
        build.setUserId(currentUserAccount);
        //获取当前IP
        build.setIp("10.19.3.36");
        AIResp aiResp = aiUtil.gpt35(build);
        String answer = "";
        if (!aiResp.getAnswerStatus().equals("SUCCESS")) {
            log.error("Ai获取OCR信息失败", JSON.toJSONString(aiResp));
        } else {
            answer = aiResp.getMessage().getContent();
            log.info("Ai获取OCR信息成功", answer);
        }
        Gson gson = new Gson();
        QualificationInfo qualificationInfo = gson.fromJson(answer, QualificationInfo.class);
        return qualificationInfo;
    }
    public EducationVO getReminderInfo(EducationInfo userEducationInfo,EducationInfo aiEducationInfo) {
        ArrayList<String> strList = new ArrayList<>();
        if (StringUtils.isNotEmpty(aiEducationInfo.getName())) {
            if (!aiEducationInfo.getName().equals(userEducationInfo.getName().replaceAll(" ",""))) {
                userEducationInfo.setName(aiEducationInfo.getName());
                strList.add("姓名");
            }
        }
        if (StringUtils.isNotEmpty(aiEducationInfo.getMajor())){
            if (!aiEducationInfo.getMajor().equals(userEducationInfo.getMajor().replaceAll(" ",""))) {
                userEducationInfo.setMajor(aiEducationInfo.getMajor());
                strList.add("学科专业");
            }
        }
        if (StringUtils.isNotEmpty(aiEducationInfo.getAwardUnit())){
            if (!aiEducationInfo.getAwardUnit().equals(userEducationInfo.getAwardUnit().replaceAll(" ",""))) {
                userEducationInfo.setAwardUnit(aiEducationInfo.getAwardUnit());
                strList.add("学位授予单位");
            }
        }
        if (StringUtils.isNotEmpty(aiEducationInfo.getDegreeDate())) {
            if (!aiEducationInfo.getDegreeDate().equals(userEducationInfo.getDegreeDate().replaceAll(" ",""))) {
                userEducationInfo.setDegreeDate(aiEducationInfo.getDegreeDate());
                strList.add("获取学位日期");
            }
        }
        if (StringUtils.isNotEmpty(aiEducationInfo.getDegreeNumber())) {
            if (!aiEducationInfo.getDegreeNumber().equals(userEducationInfo.getDegreeNumber().replaceAll(" ",""))){
                userEducationInfo.setDegreeNumber(aiEducationInfo.getDegreeNumber());
                strList.add("学位证书编号");
            }
        }
        String result = "0";
        if (strList.size()!=0) {
            result = strList.stream().collect(Collectors.joining("、")) + "--->与上传图片不一致,已帮您刷新,请再次核对。";
        }
        EducationVO educationVO = new EducationVO();
        educationVO.setEducationInfo(userEducationInfo);
        educationVO.setReminderInfo(result);
        return educationVO;
    }
}
